﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Project2.容器
{
    internal class MyQueue<T>
    {
        private T[] _array;

        private int _head;

        private int _tail;

        private int _size;

        private int _growFactor;

        private int _version;

        public MyQueue()
        {
            _array = new T[9];
        }

        public void Enqueue(T item)
        {
            if (_size == _array.Length)
            {
                SetCapacity(_size * 2);
            }

            _array[_tail] = item;
            _tail = (_tail + 1) % _array.Length;
            _size++;
            _version++;
        }

        public T Dequeue()
        {
            if (_size == 0)
            {
                throw new ArgumentOutOfRangeException("队列空");
            }
            T result = _array[_head];
            _array[_head] = (T)default;
            _head = (_head + 1) % _array.Length;
            _size--;
            _version++;
            return result;
        }

        public T Peek()
        {
            if (_size == 0)
            {
                throw new ArgumentOutOfRangeException("队列空");
            }
            return _array[_head];
        }

        public virtual void Clear()
        {
            if (_head < _tail)
            {
                Array.Clear(_array, _head, _size);
            }
            else
            {
                Array.Clear(_array, _head, _array.Length - _head);
                Array.Clear(_array, 0, _tail);
            }

            _head = 0;
            _tail = 0;
            _size = 0;
            _version++;
        }

        private void SetCapacity(int capacity)
        {
            T[] newarray = new T[capacity];
            if (_size > 0)
            {
                if (_head < _tail)
                {
                    Array.Copy(_array, _head, newarray, 0, _size);
                }
                else
                {
                    Array.Copy(_array, _head, newarray, 0, _array.Length - _head);//队头到队中的长度（数组尾）
                    Array.Copy(_array, 0, newarray, _array.Length - _head, _tail);//（数组头）队中到队尾
                }
            }

            _array = newarray;
            _head = 0;
            _tail = ((_size != capacity) ? _size : 0);//队列满了
            _version++;
        }
    }
}